/*
 * ShaderTypes.cpp
 *
 *  Created on: 1.10.2011
 *      Author: Blinov Kirill
 *      Copyright: LGPL
 */

#include "ShaderTypes.h"
#include "../Constants.h"

CShaderProgramm::CShaderProgramm( const GLuint ShaderName, const SHADER_TYPES Type ) : programmName(ShaderName)
{
	memset( (void*)paramReferences, 0, sizeof(paramReferences) );
	FillParamReferences( Type );
}

CShaderProgramm::~CShaderProgramm()
{
	glDeleteProgram( programmName );
}

bool
CShaderProgramm::InitShader( const GLuint ProgrammName, const SHADER_TYPES Type )
{
	bool result = ( 0 == programmName );
	if ( result )
	{
		programmName = ProgrammName;
		FillParamReferences( Type );
	}
	return result;
}

void
CShaderProgramm::SetParam( const SHADER_INPUT_PARAMS ParamName, const GLint Value )
{
	switch ( ParamName ) //TODO Закодить
	{
		break;default:
		{

		}
		break;
	}
}

void
CShaderProgramm::SetParam( const SHADER_INPUT_PARAMS ParamName, const float Value )
{
	if ( paramReferences[ParamName] > 0 )
	{
		glUniform1f( paramReferences[ParamName], Value );
	}
}

void
CShaderProgramm::SetParam( const SHADER_INPUT_PARAMS ParamName, const glm::vec3& Value )
{
	if ( paramReferences[ParamName] > 0 )
	{
		glUniform3fv( paramReferences[ParamName], 1, glm::value_ptr( Value ) );
	}
}

void
CShaderProgramm::SetParam( const SHADER_INPUT_PARAMS ParamName, const glm::vec4& Value )
{
	if ( paramReferences[ParamName] > 0 )
	{
		glUniform4fv( paramReferences[ParamName], 1, glm::value_ptr( Value ) );
	}
}

void
CShaderProgramm::SetParam( const SHADER_INPUT_PARAMS ParamName, const glm::mat4& Value )
{
	if ( paramReferences[ParamName] > 0 )
	{
		glUniformMatrix4fv( paramReferences[ParamName], 1, GL_FALSE, glm::value_ptr( Value ) );
	}
}

void
CShaderProgramm::SetParam( const SHADER_INPUT_PARAMS ParamName, const std::vector<glm::mat4>& Value )
{
	if ( paramReferences[ParamName] > 0 )
	{
		glUniformMatrix4fv( paramReferences[ParamName], Value.size(), GL_FALSE, glm::value_ptr( Value[0] ) );
	}
}

void
CShaderProgramm::FillParamReferences( const SHADER_TYPES Type )
{
	//Standart params
	paramReferences[SHADER_INPUT_MVP_MATRIX] = glGetUniformLocation( programmName, "MVP" );
	paramReferences[SHADER_INPUT_MODEL_MATRIX] = glGetUniformLocation( programmName, "Model" );
	paramReferences[SHADER_INPUT_LIGHT_DIRECTION] = glGetUniformLocation( programmName, "LightDir" );
	paramReferences[SHADER_INPUT_AMBLIENT_COLOR] = glGetUniformLocation( programmName, "AmblientColor" );
	paramReferences[SHADER_INPUT_CAMERA_DISTANCE] = glGetUniformLocation( programmName, "CameraDistance" );

	switch (Type)
	{
		break;case SHADER_TYPE_FONG_LIGHTING_SHADOW_VOLUME_BONES_ANIM:
		{
			paramReferences[SHADER_INPUT_MATRIX_ARRAY_32] = glGetUniformLocation( programmName, "BonesMatrix" );
		}
		break;
	}

#ifdef DEBUG_RENDERER
	fprintf( stderr, "SHADER_INPUT_MVP_MATRIX %d\n", paramReferences[SHADER_INPUT_MVP_MATRIX] );
	fprintf( stderr, "SHADER_INPUT_MODEL_MATRIX %d\n", paramReferences[SHADER_INPUT_MODEL_MATRIX] );
	fprintf( stderr, "SHADER_INPUT_LIGHT_DIRECTION %d\n", paramReferences[SHADER_INPUT_LIGHT_DIRECTION] );
	fprintf( stderr, "SHADER_INPUT_AMBLIENT_COLOR %d\n", paramReferences[SHADER_INPUT_AMBLIENT_COLOR] );
	fprintf( stderr, "SHADER_INPUT_CAMERA_DISTANCE %d\n", paramReferences[SHADER_INPUT_CAMERA_DISTANCE] );
#endif

}
